<?php

namespace ApigilityActivity\Service;

use ApigilityAddress\Service\AddressService;
use ApigilityCatworkFoundation\Base\ApigilityEventAwareObject;
use ApigilityActivity\DoctrineEntity\Review;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\Hydrator\ClassMethods as ClassMethodsHydrator;
use Zend\Hydrator\ObjectProperty as ObjectPropertyHydrator;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrineToolPaginator;
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as DoctrinePaginatorAdapter;
use Doctrine\ORM\Query\Expr;

class ReviewService extends ApigilityEventAwareObject
{
    const EVENT_Review_CREATED = 'ReviewService.EventReviewCreated';
    const EVENT_Review_NICKNAME_UPDATE = 'ReviewService.EVENT_Review_NICKNAME_UPDATE';

    protected $em;
    protected $classMethodsHydrator;
    protected $objectPropertyHydrator;

    /**
     * @var \ZF\MvcAuth\Identity\AuthenticatedIdentity
     */
    protected $authIdentity;

    protected $services;

    /**
     * @var IdentityService
     */
    protected $identityService;

    /**
     * @var OccupationService
     */
    protected $occupationService;

    /**
     * @var IncomeLevelService
     */
    protected $incomeLevelService;

    /**
     * @var AddressService
     */
    protected $addressService;

    public function __construct(ServiceManager $services)
    {

        $this->services = $services;
        $this->em = $services->get('Doctrine\ORM\EntityManager');
        $this->identityService = $services->get('ApigilityUser\Service\IdentityService');
       // $this->occupationService = $services->get('ApigilityActivity\Service\OccupationService');
       // $this->incomeLevelService = $services->get('ApigilityActivity\Service\IncomeLevelService');
        $this->addressService = $services->get('ApigilityAddress\Service\AddressService');
        $this->classMethodsHydrator = new ClassMethodsHydrator();
        $this->objectPropertyHydrator = new ObjectPropertyHydrator();

    }

    /**
     * 获取活动列表
     *
     * @param $params
     * @return DoctrinePaginatorAdapter
     */
    public function getReviews($params)
    {
        $qb = new QueryBuilder($this->em);
        $qb->select('b')->from('ApigilityActivity\DoctrineEntity\Review', 'b')->orderBy(new Expr\OrderBy('b.id', 'DESC'));

        $where = null;
        if (isset($params->position_id)) {
            $qb->innerJoin('b.positions', 'p');
            if (!empty($where)) $where .= ' AND ';
            $where = 'p.id = :position_id';
        }

        if (!empty($where)) {
            $qb->where($where);
            if (isset($params->position_id)) $qb->setParameter('position_id', $params->position_id);
        }

        $doctrine_paginator = new DoctrineToolPaginator($qb->getQuery());
        return new DoctrinePaginatorAdapter($doctrine_paginator);
    }


    /**
     * 创建一个活动评论
     * @param $data
     * @return Review
     */
    public function createReview($data)
    {
        $Review = new Review();
        
        $this->hydrateReviewData($Review, $data);

        $this->em->persist($Review);
        $this->em->flush();

        $this->getEventManager()->trigger(self::EVENT_Review_CREATED, $this, ['Review' => $Review]);

        return $Review;
    }

    /**
     * 获取单个活动评论信息
     *
     * @param $Review_id
     * @return \ApigilityActivity\DoctrineEntity\Review
     * @throws Exception\ReviewNotExistException
     */
    public function getReview($Review_id)
    {
        $Review = $this->em->find('ApigilityActivity\DoctrineEntity\Review', $Review_id);
        if (empty($Review)) throw new Exception\ReviewNotExistException();
        return $Review;
    }

    
    /**
     * @param Review $Review
     * @param $data
     */
    private function hydrateReviewData(Review $Review, $data)
    {
        if (isset($data->content)) $Review->setContent($data->content);
        if (isset($data->uid)) $Review->setUid($data->uid);
        if (isset($data->ac_id)) $Review->setAcid($data->ac_id);
        $Review->setAddedTime(time());
    }
}